package org.example.java.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.example.java.exception.NotFoundException;
import org.example.java.exception.StandardException;
import org.example.java.model.User;
import org.example.java.model.UserProfile;
import org.example.java.request.UserUpdateRequest;
import org.example.java.service.impl.UserProfileServiceImpl;
import org.example.java.service.impl.UserServiceImpl;
import org.example.java.request.UserCreateRequest;
import org.example.java.request.UserListRequest;
import org.example.java.vo.UserDetailVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Api(tags = "User")
@RestController
@RequestMapping("/api/users")
public class UserProfileController {

    @Autowired
    private UserProfileServiceImpl userProfileService;
    @Autowired
    private UserServiceImpl userService;

    public UserDetailVO getUserDetailVO(User user, UserProfile userProfile) {
        UserDetailVO userDetailVO = new UserDetailVO();

        userDetailVO.setStatus(user.getStatus());
        userDetailVO.setUserId(userProfile.getUserId().toString());
        userDetailVO.setName(userProfile.getName());
        userDetailVO.setEmail(userProfile.getEmail());
        userDetailVO.setDob(userProfile.getDob());
        userDetailVO.setCreatedAt(userProfile.getCreatedAt());
        userDetailVO.setLastModifiedAt(userProfile.getLastModifiedAt());

        return userDetailVO;
    }

    @Transactional
    @ApiOperation(value = "Create a user")
    @PostMapping()
    public UserDetailVO createUser(@RequestBody UserCreateRequest userCreateRequest) throws Exception {
        Map<String, Object> o = userProfileService.createUserProfile(userCreateRequest);
        return getUserDetailVO((User) o.get("user"), (UserProfile) o.get("userProfile"));
    }

    @ApiOperation(value = "Update a user")
    @PutMapping("{userId}")
    public UserDetailVO updateUser(@PathVariable Long userId, @RequestBody UserUpdateRequest userUpdateRequest) throws Exception {
        Map<String, Object> o = userProfileService.updateUserProfile(userId, userUpdateRequest);
        return getUserDetailVO((User) o.get("user"), (UserProfile) o.get("userProfile"));
    }

    @ApiOperation(value = "Get user profile by user id")
    @GetMapping("{userId}")
    public UserDetailVO getById(@PathVariable Long userId) throws Exception {
        User user = userService.getById(userId);
        if (user == null) {
            throw new NotFoundException("user not found");
        }
        UserProfile userProfile = userProfileService.getByUserId(userId);
        if (userProfile == null) {
            throw new NotFoundException("user not found");
        }

        return getUserDetailVO(user, userProfile);
    }

    @ApiOperation(value = "Get user profile by username")
    @GetMapping("getByName")
    public UserDetailVO getByName(@RequestParam(name = "name", defaultValue = "") String name) throws Exception {
        UserProfile userProfile = userProfileService.getByName(name);
        if (userProfile == null) {
            throw new NotFoundException("user profile not found");
        }
        User user = userService.getById(userProfile.getUserId());
        if (user == null) {
            throw new NotFoundException("user not found");
        }

        return getUserDetailVO(user, userProfile);
    }

    @ApiOperation(value = "list user")
    @GetMapping()
    public Page<UserDetailVO> listByPage(@RequestParam(name = "currentPage", defaultValue = "1") int currentPage,
                                  @RequestParam(name = "count", defaultValue = "10") int count,
                                  UserListRequest userListVo) throws Exception {
        try {
            Page<UserProfile> page = new Page<>(currentPage, count);
            QueryWrapper<UserProfile> queryWrapper = new QueryWrapper<>();
            if (!StringUtils.isEmpty(userListVo.getName())) {
                queryWrapper.like("name", userListVo.getName());
            }
            Page<UserProfile> profilePage = userProfileService.page(page, queryWrapper);
            List<UserDetailVO> userDetailVOs = profilePage.getRecords().stream().map(userProfile -> {
                User user = userService.getById(userProfile.getUserId());
                return getUserDetailVO(user, userProfile);
            }).collect(Collectors.toList());
            Page<UserDetailVO> userDetailVOPage = new Page<>(profilePage.getCurrent(), profilePage.getSize(), profilePage.getTotal());
            userDetailVOPage.setRecords(userDetailVOs);
            return userDetailVOPage;
        } catch (Exception e) {
            throw new Exception(e);
        }
    }

    @ApiOperation(value = "Delete a user by id")
    @DeleteMapping("{userId}/delete")
    public boolean deleteUser(@PathVariable Long userId) {
        return userProfileService.removeByUserId(userId);
    }
}
